package consumer;

import java.util.LinkedList;
import java.util.Random;

import proxy.ServerNode;
import proxy.UnitContainer;
import proxy.VideoUnit;
import simulation.Simulator;
import simulation.SimulatorConfig.ScenarioType;

/**
 * This consumer model is used to investigate how long it takes such that all
 * users get one unit
 * 
 * @author Anita
 * 
 */
public class InformationDisseminationConsumer extends Consumer {

	boolean done = false;

	public InformationDisseminationConsumer(int id, Simulator simulator,
			ServerNode server, Random rand) {
		super(id, simulator, server, rand);
		favoriteList = new LinkedList<VideoUnit>();
		favoriteList.add((VideoUnit) simulator.getVideoUnitDirectory().get(0)
				.clone());

	}

	@Override
	public void processMixed() {
		// nothing to do
		processSequence();
	}

	@Override
	public void processParallel() {
		// nothing to do
		processSequence();
	}

	@Override
	public void processSequence() {
		// sequence of one unit
		if (currentlyViewing == null) {
			// either new request or check if it is here

			if (viewings.size() == 0) {
				Viewing vi = new Viewing(favoriteList.get(0),
						simulator.getSimTime());
				vi.setRequestTime(simulator.getSimTime());
				viewings.add(vi);
				server.increaseInterest(viewings, true, true);
				simulator.requestSubmittedCounter++;
				simulator.log("C" + this.getId() + " req sent");
			} else {
				Viewing current = viewings.get(0);
				UnitContainer uc = server.searchPresentUnit(current
						.getVideoUnit().getId());
				if (uc == null) {
					// Gossip pull - periodically searching for a node that has
					// the requested unit
					if (simulator.getScenario() == ScenarioType.GOSSIP) {
						server.increaseInterest(viewings, false, true);
					}

				} else {
					double delay;
					if (uc.getTimeReceived() <= current.getRequestTime()) {
						delay = 0.0;
					} else {
						delay = uc.getTimeReceived() - current.getRequestTime();
					}
					simulator.delayStat.add(delay);
					simulator.requestFulfilledCounter++;
					currentlyViewing = current;
					done = true;
				}
			}
		}
	}

	@Override
	public void chooseFavorites() {
		// only one unit from the beginning
	}

	@Override
	public void kill() {

		// only online nodes count for coverage
		//but delay has to be measured
		if (!done) {
			simulator.requestSubmittedCounter--;
			simulator.delayStat.add(simulator.getSimTime()
					- viewings.get(0).getRequestTime());
		}
	}
}
